package com.hyt.it.ogt.ks.service.impl;

import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.core.toolkit.Wrappers;
import com.hyt.common.apiInfor.ApiResponse;
import com.hyt.core.base.BaseServiceImpl;
import com.hyt.it.ogt.ks.api.kw.model.CandidateUseTimeDTO;
import com.hyt.it.ogt.ks.config.KsBizRunTimeException;
import com.hyt.it.ogt.ks.enums.BizStatusCode;
import com.hyt.it.ogt.ks.feign.KwClient;
import com.hyt.it.ogt.ks.feign.model.ExamCandidate;
import com.hyt.it.ogt.ks.feign.model.KwExamCandidate;
import com.hyt.it.ogt.ks.mapper.CandidatePaperMapper;
import com.hyt.it.ogt.ks.mapper.CandidateProcessMapper;
import com.hyt.it.ogt.ks.mapper.PaperTopicMapper;
import com.hyt.it.ogt.ks.model.entity.CandidatePaper;
import com.hyt.it.ogt.ks.model.entity.CandidateProcess;
import com.hyt.it.ogt.ks.model.entity.CandidateTimeLength;
import com.hyt.it.ogt.ks.model.vo.AnswerTimeVO;
import com.hyt.it.ogt.ks.model.vo.CandidateSubjectPaperInfoVO;
import com.hyt.it.ogt.ks.model.xyvo.XyCandidateUseTimeVO;
import com.hyt.it.ogt.ks.model.xyvo.XyScoreVO;
import com.hyt.it.ogt.ks.service.IAnswerProgressService;
import com.hyt.it.ogt.ks.service.ICandidateAnswerBackupService;
import com.hyt.it.ogt.ks.service.ICandidatePaperService;
import com.hyt.it.ogt.ks.service.ILogService;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.lang3.StringUtils;
import org.springframework.stereotype.Service;

import javax.annotation.Resource;
import java.math.BigDecimal;
import java.util.List;
import java.util.Objects;


/**
 * <p>
 * </p>
 *
 * @author chengxh
 * @since 2020-06-17
 */

@Slf4j
@Service
public class CandidatePaperServiceImpl extends BaseServiceImpl<CandidatePaperMapper, CandidatePaper> implements ICandidatePaperService {
    @Resource
    private PaperTopicMapper paperTopicMapper;
    @Resource
    private ILogService iLogService;
    @Resource
    private KwClient kwClient;
    @Resource
    private ICandidateAnswerBackupService iCandidateAnswerBackupService;
    @Resource
    private CandidateProcessMapper candidateProcessMapper;
    @Resource
    private IAnswerProgressService iAnswerProgressService;

    @Override
    public Integer getFirstPaperType(String examId, String candidateId) {
        CandidatePaper paper = super.getOne(Wrappers.<CandidatePaper>lambdaQuery().select(CandidatePaper::getPaperType)
                .eq(CandidatePaper::getExamId, examId).eq(CandidatePaper::getCandidateId, candidateId)
                .eq(CandidatePaper::getFinish, false).gt(CandidatePaper::getMixSort, 0)
                .orderByAsc(CandidatePaper::getMixSort).last("limit 1"));
        if(paper != null) {
            return paper.getPaperType();
        } else {
            return null;
        }
    }

    @Override
    public CandidateTimeLength getTimeLength(String examId, String candidateId, Integer sort) {
        CandidateTimeLength cl = new CandidateTimeLength();
        cl.setExamId(examId);
        cl.setCandidateId(candidateId);
        LambdaQueryWrapper<CandidateProcess> query = Wrappers.<CandidateProcess>lambdaQuery()
                .select(CandidateProcess::getId, CandidateProcess::getExamStatus,
                        CandidateProcess::getForbidFinishExam, CandidateProcess::getBeginTime)
                .eq(CandidateProcess::getExamId , examId).eq(CandidateProcess::getCandidateId, candidateId);
        CandidateProcess candidateProcess = candidateProcessMapper.selectOne(query);
        cl.setId(candidateProcess.getId());
        ApiResponse<Boolean> res = kwClient.getCandidateForbidEndExam(candidateId);
        if (res.getCode().intValue() == BizStatusCode.KW_SUCCESS_OK.getCode().intValue()) {
            cl.setForbidFinishExam(res.getData());
        } else {
            cl.setForbidFinishExam(false);
        }
        cl.setBeginTime(candidateProcess.getBeginTime());
        cl.setExamStatus(candidateProcess.getExamStatus());
        CandidatePaper candidatePaper = this.lambdaQuery().select(CandidatePaper::getAccessTime,
                CandidatePaper::getPaperTimeLength, CandidatePaper::getExamUseTime, CandidatePaper::getExtraTime,
                CandidatePaper::getHandInTime, CandidatePaper::getRemainingTime, CandidatePaper::getId)
                .eq(CandidatePaper::getExamId, examId).eq(CandidatePaper::getCandidateId, candidateId)
                .eq(CandidatePaper::getMixSort, sort).one();
        cl.setCandidatePaperId(candidatePaper.getId());
        cl.setExtraTime(candidatePaper.getExtraTime());
        cl.setRemainingTime(candidatePaper.getRemainingTime());
        cl.setAccessTime(candidatePaper.getAccessTime());
        cl.setExamUseTime(candidatePaper.getExamUseTime());
        cl.setHandInTime(candidatePaper.getHandInTime());
        cl.setPaperTimeLength(candidatePaper.getPaperTimeLength());
        return cl;
    }

    @Override
    public int updateTimeRef(String examId, String candidateId) {
        return baseMapper.updateTimeRef(examId, candidateId);
    }

    @Override
    public void updateFinishPage(String candidateId, String examId, Integer sort, Integer current) {
        CandidatePaper paper = baseMapper.selectOne(Wrappers.<CandidatePaper>lambdaQuery().select(CandidatePaper::getId)
                .eq(CandidatePaper::getExamId, examId).eq(CandidatePaper::getCandidateId, candidateId)
                .eq(CandidatePaper::getMixSort, sort));
        paperTopicMapper.updateFinishState(paper.getId(), current);
    }

    @Override
    public void updateFinishAllPage(String candidateId, String examId, Integer sort) {
        baseMapper.updateFinishAllPage(candidateId, examId, sort);
    }

    @Override
    public List<CandidateUseTimeDTO> getCandidateUseTime(String examId, String candidateId) {
        return baseMapper.getCandidateUseTime(examId, candidateId);
    }

    @Override
    public void cancelPackageCommit(String examId, String candidateId, String ids, Integer isBackup,
                                    Integer logBackup, String userId) {
        //先处理如果答题表移动至备份表
        if(Objects.equals(1,isBackup)){
            iCandidateAnswerBackupService.cancelPackageCommit(examId,candidateId,logBackup);
        }
        String[] arr = ids.split(",");
        for (String s : arr) {
            this.lambdaUpdate().set(CandidatePaper::getFinish, false).eq(CandidatePaper::getId, s).update();
            CandidatePaper candidatePaper = this.lambdaQuery()
                    .select(CandidatePaper::getExamId, CandidatePaper::getCandidateId,
                            CandidatePaper::getPaperId, CandidatePaper::getPaperVersion)
                    .eq(CandidatePaper::getId, s).one();
            KwExamCandidate examCandidate = new KwExamCandidate();
            examCandidate.setId(candidatePaper.getCandidateId());
            examCandidate.setCancelFinishExamState(true);
            kwClient.updateCandidate(examCandidate);
            //调用一下清理考试计时时度
            iAnswerProgressService.resetAnswerTimeCancelPaper(examId,candidateId,s);
            try{
                iLogService.cancelPackageCommitLog(candidatePaper, userId);
            }catch (Exception e){
                log.error("{}", e);
            }
        }
    }

    @Override
    public int updateExtraTimeByExamId(String examId, Long extraTime) {
        return baseMapper.updateExtraTimeByExamId(examId, extraTime);
    }

    @Override
    public CandidatePaper getCandidatePaper(String examId, String candidateId, String paperId, String paperVersion) {
        return baseMapper.getCandidatePaper(examId, candidateId, paperId, paperVersion);
    }

    @Override
    public int addTimeByBatch(String examId, String paperId, String paperVersion, Long timeLength) {
        return baseMapper.addTimeByBatch(examId, paperId, paperVersion, timeLength);
    }

    @Override
    public List<String> getAddedTimeCandidate(String examId, String paperId, String paperVersion) {
        return baseMapper.getAddedTimeCandidate(examId, paperId, paperVersion);
    }
    
    @Override
    public BigDecimal getPaperKgScore(String examId, String admissionNumber, String paperId, String paperVersion) {
    	CandidatePaper candidatePaper = super.getOne(Wrappers.<CandidatePaper>lambdaQuery()
    			.eq(CandidatePaper::getExamId, examId)
                .eq(CandidatePaper::getAdmissionNumber, admissionNumber)
                .eq(CandidatePaper::getPaperId, paperId)
                .eq(CandidatePaper::getPaperVersion, paperVersion)
                .last("limit 1"));
    	if(candidatePaper == null) {
    		return BigDecimal.ZERO;
    	}
    	return candidatePaper.getObjectiveScore() == null ? BigDecimal.ZERO : candidatePaper.getObjectiveScore();
    }
    
    @Override
    public XyScoreVO getXyScore(String candidateId) {
        //用与判断是否已备份考生答题表
        String acRes = kwClient.getExamCandidateById(candidateId);
        log.info("调用考务系统获取考生信息，：{}",acRes);
        if(StringUtils.isBlank(acRes)){
            throw new KsBizRunTimeException();
        }
        ApiResponse<ExamCandidate> ecResponse = ApiResponse.ConvertRet(acRes,ExamCandidate.class);
        if(!Objects.equals(ecResponse.getCode(), BizStatusCode.KW_SUCCESS_OK.getCode()) || Objects.isNull(ecResponse.getData())){
            log.error("调用考务系统获取考生信息失败，返回信息为:{}",ecResponse);
            throw new KsBizRunTimeException();
        }
        ExamCandidate ac = ecResponse.getData();
        if(Objects.equals(1,ac.getIsBackup())){
            return baseMapper.getXyScoreWhenBackup(candidateId);
        }
        return baseMapper.getXyScore(candidateId);
    }
    
    @Override
    public XyCandidateUseTimeVO getXyCandidateUseTime(String candidateId) {
    	return baseMapper.getXyCandidateUseTime(candidateId);
    }
    
    @Override
    public AnswerTimeVO getExamAnswerTime(String examId) {
    	return baseMapper.getExamAnswerTime(examId);
    }
    
    @Override 
    public List<CandidateSubjectPaperInfoVO> getCandidateSubjectPaperInfo(String examId, String admissionNumber) {
    	return baseMapper.getCandidateSubjectPaperInfo(examId, admissionNumber);
    }

    @Override
    public List<CandidateSubjectPaperInfoVO> findCandidateSubjectPaperInfoList(String examId, List<String> candidateIds) {
    	return baseMapper.findCandidateSubjectPaperInfoList(examId, candidateIds);
    }

    @Override
    public List<CandidateUseTimeDTO> getCandidateUseTimeByCandidateIds(String examId, List<String> candidateIds) {
        return baseMapper.getCandidateUseTimeByCandidateIds(examId, candidateIds);
    }
}
